﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using Plasmoid.Extensions;

namespace ReversiFrontend
{
    public enum Border
    {
        North,
        East,
        South,
        West
    }

    public delegate void BaseColorChangedHandler();

    public partial class MyPanel : Panel
    {
        public static event BaseColorChangedHandler BaseColorChanged;

        public MyPanel()
        {
            InitializeComponent();
            DoubleBuffered = true;
            MyPanel.BaseColorChanged += new BaseColorChangedHandler(MyPanel_BaseColorChanged);
           // this.Paint += new PaintEventHandler(MyPanel_Paint);
        }

        void MyPanel_BaseColorChanged()
        {
            this.Invalidate();
        }

        private static System.Drawing.Color baseColor = System.Drawing.SystemColors.ActiveCaption;

        public static System.Drawing.Color BaseColor
        {
            get
            {
                if (MyPanel.baseColor != null)
                {
                    return MyPanel.baseColor;
                }
                else
                {
                    return System.Drawing.SystemColors.ActiveCaption;
                }
            }
            set
            {
                MyPanel.baseColor = value;
                if (BaseColorChanged != null)
                {
                    BaseColorChanged();
                }
            }
        }

        private Border border = Border.South;
        public Border Border
        {
            get
            {
                return border;
            }
            set
            {
                if (value != border)
                {
                    border = value;
                    Invalidate();
                }
            }
        }

        int borderWidth = 0;
        public int BorderWidth
        {
            get { return borderWidth; }
            set
            {
                if (value != borderWidth)
                {
                    borderWidth = value;
                    Invalidate();
                }
            }
        }
        protected override void  OnPaint(PaintEventArgs e)
{

            Graphics g = e.Graphics;
            
            g.SmoothingMode = SmoothingMode.AntiAlias;
           // if (sender is MyPanel)
            //{   
                
                if (borderWidth != 0)
                {
                    switch (Border)
                    {
                        case Border.North:
                            drawRect(g, new Rectangle(0, borderWidth, Width, Height - borderWidth));
                            drawRect(g, new Rectangle(Width / 4 - 10, 0, 20, borderWidth));
                            drawRect(g, new Rectangle(Width * 3 / 4 - 10, 0, 20, borderWidth));
                            break;
                        case Border.South:
                            drawRect(g, new Rectangle(0, 0, Width, Height - borderWidth));
                            drawRect(g, new Rectangle(Width / 4 - 10, Height - borderWidth, 20, borderWidth));
                            drawRect(g, new Rectangle(Width * 3 / 4 - 10, Height - borderWidth, 20, borderWidth));
                            break;
                        case Border.East:
                            drawRect(g, new Rectangle(0, 0, Width - borderWidth, Height));
                            drawRect(g, new Rectangle(Width - borderWidth, Height / 4 - 10, borderWidth, 20));
                            drawRect(g, new Rectangle(Width - borderWidth, Height * 3 / 4 - 10, borderWidth, 20));
                            break;
                        case Border.West:
                            drawRect(g, new Rectangle(borderWidth, 0, Width - borderWidth, Height));
                            drawRect(g, new Rectangle(0, Height / 4 - 10, borderWidth, 20));
                            drawRect(g, new Rectangle(0, Height * 3 / 4 - 10, borderWidth, 20));
                            break;
                    }
                }
                else
                {
                    drawRect(g, new Rectangle(0, 0, Width, Height));
                }
           // }
           
           // drawRect(g, new Rectangle(10, 0, 200, 35));
            //drawRect(g, new Rectangle(0, 40, Width - 155, Height - 40));
            //drawRect(g, new Rectangle(Width - 150, 140, 150, Height - 140 * 2));

        }

        protected override void OnResize(EventArgs eventargs)
        {
            base.OnResize(eventargs);
            Invalidate();
        }


        private void drawRect(Graphics g, Rectangle r)
        {
            Color backCol = ControlPaint.Dark(MyPanel.BaseColor, 0.2f);
            Color surroundCol = ControlPaint.Light(MyPanel.BaseColor, 0.00f);
            Color lightCol = ControlPaint.Light(MyPanel.BaseColor, 0.95f);
            Color darkCol = ControlPaint.Dark(MyPanel.BaseColor, 0.5f);
            # region Style-specific stuff
            if (MyPanel.BaseColor == Color.DeepPink) //hello kitty
            {
                lightCol = Color.White;
                darkCol = ControlPaint.Light(MyPanel.BaseColor, 0.99f);
                surroundCol = Color.White;
                backCol = MyPanel.BaseColor;
            }
            else if (MyPanel.BaseColor == SystemColors.ActiveCaption) //default
            {
                lightCol = SystemColors.GradientInactiveCaption;
            }
            else if (MyPanel.BaseColor == Color.Black) //dark
            {
                lightCol = Color.Silver;
                surroundCol = Color.LightSlateGray;
            }
            #endregion
            g.FillRoundedRectangle(new SolidBrush(backCol),
                               r, 10);
            LinearGradientBrush brush = new LinearGradientBrush(
                new Point(r.Width / 2, r.Top),
                new Point(r.Width / 2, r.Bottom),
                lightCol, darkCol);
            g.FillRoundedRectangle(brush, r.Left + 2, r.Top + 2, r.Width - 4, r.Height - 4, 10);
            g.DrawRoundedRectangle(new Pen(surroundCol), r.Left + 2, r.Top + 2, r.Width - 4, r.Height - 4, 10);
            //       g.FillRoundedRectangle(new SolidBrush(Color.FromArgb(100, 70, 130, 180)),
            //         r.Left + 2, r.Top + 2 + ((r.Height - 4) / 2), r.Width - 4, (r.Height - 4)/2, 10);

        }

        #region collapse/expand animation stuff
        // zu zeichnende höhe/breite (je nach border) ohne rand
        private int OrigWidth, OrigHeight;
        private bool animating = false;
        Timer t;

        public void Collapse(Callback c)
        {
            StartAnim(-1, c);
        }
        public void Expand(Callback c)
        {
            StartAnim(1, c);
        }
        public delegate void Callback();

        //non-generic version that can only anim vertically
        private void StartAnim(int dir, Callback c)
        {
            if (t != null)
            {
                t.Stop();
            }
            t = new Timer();
            t.Interval = 20;
            
            if (dir == -1)
            {
                if (!animating)
                {
                    OrigHeight = Height;
                }
                t.Tick += new EventHandler((sender, args) =>
                {
                    if ((Height -= 20) < BorderWidth + 20)
                    {
                        Height = BorderWidth + 10;
                        t.Stop();
                        animating = false;
                        c();
                    }
                });
            }
            else if (dir == 1)
            {
                t.Tick += new EventHandler((sender, args) =>
                {
                    if ((Height += 20) > OrigHeight)
                    {
                        Height = OrigHeight;
                        t.Stop();
                        animating = false;
                        c();
                    }
                });
            }
            animating = true;
            t.Enabled = true;


        }

        //private void StartAnim(int dir, Callback c)
        //{
        //    animating = true;
        //    Timer t = new Timer();
        //    t.Interval = 20;
        //    int maxDrawSize = OrigWidth;
        //    if (Border == Border.North || Border == Border.South){
        //        maxDrawSize = OrigHeight;}
        //        if (dir == -1){
        //        t.Tick += new EventHandler((sender, args) =>
        //                                        {
        //                                            if ((drawSize-=5) < BorderWidth + 10)
        //                                            {
        //                                                drawSize = BorderWidth + 10;
        //                                                t.Stop();
        //                                                animating = false;
        //                                                c();
        //                                            }
        //                                            else
        //                                            {
        //                                                Invalidate();
        //                                            }
        //                                        });
        //        }
        //        else if (dir == 1) {
        //        t.Tick += new EventHandler((sender, args) =>
        //                                        {
        //                                            if ((drawSize+=5) > maxDrawSize)
        //                                            {
        //                                                drawSize = maxDrawSize;
        //                                                t.Stop();
        //                                                animating = false;
        //                                                c();
        //                                            }
        //                                            else
        //                                            {
        //                                                Invalidate();
        //                                            }
        //                                        });
        //        }
        //        t.Enabled = true;

            
        //}

        #endregion
    }
}
